/*
 *@Type SocketServerHandler.java
 * @Desc
 * @Author urmsone urmsone@163.com
 * @date 2024/6/13 12:50
 * @version
 */
package controller;

import dto.ActionDTO;
import dto.ActionTypeEnum;
import dto.RespDTO;
import dto.RespStatusTypeEnum;
import handler.ActionHandler;
import handler.GetActionHandler;
import handler.RmActionHandler;
import handler.SetActionHandler;
import service.NormalStore;
import service.Store;
import utils.LoggerUtil;

import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class SocketServerHandler implements Runnable {
    private final Logger LOGGER = LoggerFactory.getLogger(SocketServerHandler.class);
    private Socket socket;
    private Store store;
    private final Map<ActionTypeEnum, ActionHandler> handlerMap = new HashMap<>();

    public SocketServerHandler(Socket socket, Store store) {
        this.socket = socket;
        this.store = store;
        initializeHandlers();
    }

    private void initializeHandlers() {
        handlerMap.put(ActionTypeEnum.GET, new GetActionHandler());
        handlerMap.put(ActionTypeEnum.SET, new SetActionHandler());
        handlerMap.put(ActionTypeEnum.RM, new RmActionHandler());
    }

    @Override
    public void run() {
        try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
             ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {

            // 接收序列化对象
            ActionDTO dto = (ActionDTO) ois.readObject();
            LoggerUtil.debug(LOGGER, "[SocketServerHandler][ActionDTO]: {}", dto.toString());
            System.out.println("" + dto.toString());

            // 处理命令逻辑
            // 动态适配模式
            ActionHandler handler = handlerMap.get(dto.getType());
            if (handler != null){
                handler.handle(store, dto, oos);
            }else {
                // 处理未知操作类型
                RespDTO resp = new RespDTO(RespStatusTypeEnum.FAIL, "Unknown operation");
                oos.writeObject(resp);
                oos.flush();
            }

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
